package com.centerm.bluetooth.core.controller;

import android.content.Context;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;

import com.centerm.bluetooth.core.controller.constants.WaitEnum;
import com.centerm.bluetooth.core.listener.IBluetoothDataReceiveListener;
import com.centerm.bluetooth.core.listener.base.IErrorListener;
import com.centerm.bluetooth.ibridge.BluetoothIBridgeDevice;
import com.centerm.bluetooth.model.Respond;
import com.centerm.util.Logger;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by linwenhui on 2017/2/16.
 * 指令逻辑控制类
 */
public abstract class BaseController<T extends IErrorListener> implements IBluetoothDataReceiveListener {
    protected final static int DEFAULT_TIMEOUT = 60;
    protected Context context;
    private BluetoothController bluetoothController;
    protected T baseListener;
    private Timer timeoutTimer;
    protected static WaitEnum wait;//保证一问一答
    protected final byte key;

    public BaseController(byte key, @NonNull Context context) {
        this.key = key;
        this.context = context;
        bluetoothController = BluetoothController.getInstance(context);
        wait = WaitEnum.FREE;
        registerBluetoothListener();
    }

    /**
     * 注册蓝牙数据监听
     */
    protected synchronized final void registerBluetoothListener() {
        bluetoothController.registerBluetoothListener(key, this);
    }

    /**
     * 取消蓝牙数据监听
     */
    protected synchronized final void unRegisterBluetoothListener() {
        wait = WaitEnum.FREE;
        bluetoothController.unRegisterBluetoothListener(key);
    }

    public void resetSDKStatus() {
        wait = WaitEnum.FREE;
    }

    /**
     * 指令逻辑控制类回调
     *
     * @param baseListener
     */
    public void setListener(@NonNull T baseListener) {
        this.baseListener = baseListener;
    }

    /**
     * 向蓝牙设备发送数据
     *
     * @param cmd
     * @param params
     * @throws IOException
     */
    protected synchronized boolean send(@NonNull byte[] cmd, byte[] params) throws IOException {
        boolean status = bluetoothController.send(cmd, params);
        if (status) {
            wait = WaitEnum.WAIT;
        }
        return status;
    }

    /**
     * 向设计设备发送数据并设置超时定时器
     *
     * @param cmd
     * @param params
     * @param timeout
     * @throws IOException
     */
    public synchronized boolean sendAndStartTimer(@NonNull byte[] cmd, byte[] params, @IntRange(from = 1) int timeout) throws IOException {
        boolean status = bluetoothController.send(cmd, params);
        if (status) {
            wait = WaitEnum.WAIT;
            setTimeOut(timeout);
        }
        return status;
    }

    /**
     * 向设计设备发送数据并设置超时定时器,定时10s
     *
     * @param cmd
     * @param params
     * @throws IOException
     */
    public synchronized void sendAndStartTimer(@NonNull byte[] cmd, byte[] params) throws IOException {
        sendAndStartTimer(cmd, params, DEFAULT_TIMEOUT);
    }

    /**
     * 设置超时定时器，定时10s
     */
    protected void setTimeoutTimer() {
        setTimeOut(DEFAULT_TIMEOUT);
    }

    /**
     * 设置超时定时器
     *
     * @param time
     */
    protected synchronized void setTimeOut(@IntRange(from = 1) int time) {
        if (timeoutTimer != null)
            timeoutTimer.cancel();
        timeoutTimer = new Timer();
        timeoutTimer.schedule(new CommandTimeout(), time * 1000);
    }

    /**
     * 取消超时定时器
     */
    protected synchronized void cancelTimer() {
        wait = WaitEnum.FREE;
        if (timeoutTimer != null)
            timeoutTimer.cancel();
        timeoutTimer = null;
    }

    @Override
    public synchronized void onDataReceived(BluetoothIBridgeDevice device, Respond respond) {
        cancelTimer();
    }

    @Override
    public synchronized void onDataReceivedError(BluetoothIBridgeDevice device, Respond respond) {
        Logger.i(" == onDataReceivedError == ");
        cancelTimer();
        if (baseListener != null)
            baseListener.onError(respond.getRespondStatus().getStatus(), respond.getRespondStatus().getMsg());
    }

    @Override
    protected void finalize() throws Throwable {
        unRegisterBluetoothListener();
        super.finalize();
    }

    private class CommandTimeout extends TimerTask {
        @Override
        public void run() {
            Logger.i(" == CommandTimeout == ");
            wait = WaitEnum.FREE;
            if (baseListener != null) {
                baseListener.onTimeout();
            }
        }
    }
}
